﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using PH.Common;
using PH.Map;

namespace Hoshimi.Final
{
    #region protector
    [Characteristics(ContainerCapacity = 0,
    CollectTransfertSpeed = 0,
    Scan = 5,
    MaxDamage = 5,
    DefenseDistance = 5,
    Constitution = 35)]

    class MiNanoProtector : NanoCollector
    {
        public void DoNextProtector(MyAI player)
        {
            InternalName = "Protector";

            this.MoveTo(player.AI.Location);
            if (player.PierreExtinto == true) { player.NesesitaProteccion = false; this.ForceAutoDestruction(); }

            Defensa.defenderse(player, this);
        }

    }
    #endregion

    #region container
    [Characteristics(ContainerCapacity = 50,
    CollectTransfertSpeed = 5,
    Scan = 0,
    MaxDamage = 0,
    DefenseDistance = 0,
    Constitution = 15)]

    class MiNanoContainer : NanoContainer
    {

        //enumero los estados posibles de un colector
        public enum EstadoContainer
        {
            BuscandoAzn,
            RecolectadoAzn,
            BuscandoNeedle,
            TransfiriendoAzn
        }
        //EstadoContainer ProximaAccion = EstadoContainer.BuscandoAzn;
        
        //List<Point> lstHoshimiPointsOrdenadosExeptuados = new List<Point>();
        //Point puntoDestino;

        EstadoContainer ProximaAccion = EstadoContainer.BuscandoAzn;
        List<Point> lstHPconAgujasLlenas = new List<Point>();
        List<Point> lstHPconAgujasAux = new List<Point>();
        Point AZNcenrcano;
        Point HPcercano;
        bool flag = false;

        public void DoNextConteiner(MyAI player, int Recorrido)
        {
            InternalName = "Contenedores";

            if (flag == false)
            {
                AZNcenrcano = Util.PuntoMasCercano(Util.PuntoMasCercano(this.Location, player.lstHoshimiPointsOrdenados, lstHPconAgujasLlenas), player.lstAzn);
                flag = true;
            }
            

            switch (ProximaAccion)
            {
                #region BuscandoAzn
                case EstadoContainer.BuscandoAzn:
                    
                        if ((this.Location != AZNcenrcano) && (this.State == NanoBotState.WaitingOrders))                                              
                                MoveTo(AZNcenrcano);
                       
                        else
                        {
                            this.StopMoving();
                            AZNcenrcano = Util.PuntoMasCercano(Util.PuntoMasCercano(this.Location, player.lstHoshimiPointsOrdenados, lstHPconAgujasLlenas), player.lstAzn);
                            ProximaAccion = EstadoContainer.RecolectadoAzn;
                        }
                        break;
                #endregion

                #region RecolectadoAzn
                case EstadoContainer.RecolectadoAzn:
                    if (this.Stock == this.ContainerCapacity)
                    {
                        ProximaAccion = EstadoContainer.BuscandoNeedle;
                    }
                    else
                    {
                        this.CollectFrom(this.Location, 10);
                        ProximaAccion = EstadoContainer.BuscandoNeedle;
                    }
                    break;
                #endregion

                #region BuscandoNeedle
                case EstadoContainer.BuscandoNeedle:

                    if ((this.Stock != 0) && (this.State == NanoBotState.WaitingOrders))
                    {
                        this.MoveTo(((MyAI)this.PlayerOwner).lstHoshimiPointsOrdenados[((MyAI)this.PlayerOwner).contador_de_grupo]);
                        if (((MyAI)this.PlayerOwner).aum_cont == true)
                        {
                            if (((MyAI)this.PlayerOwner).contador_de_grupo < ((MyAI)this.PlayerOwner).lstHoshimiPointsOrdenados.Count - 1)
                            {
                                ((MyAI)this.PlayerOwner).contador_de_grupo++;
                                ((MyAI)this.PlayerOwner).aum_cont = false;
                            }

                        }
                        else
                        {
                            ((MyAI)this.PlayerOwner).aum_cont = true;
                        }

                        this.ProximaAccion = EstadoContainer.TransfiriendoAzn;
                    }
                    else
                        this.ProximaAccion = EstadoContainer.TransfiriendoAzn;
                    break;
                #endregion

                #region TransfiriendoAzn
                case EstadoContainer.TransfiriendoAzn:
                    //if(this.Location)
                    this.TransferTo(this.Location, 10);
                    //lstHPconAgujasLlenas.Add(this.Location);
                    //lstHPconAgujasAux.Remove(this.Location);
                    if (this.Stock == 0)
                    {
                          ProximaAccion = EstadoContainer.BuscandoAzn;
                    }
                  
                    break;
                #endregion
            }

        }

    }
    #endregion

    #region objetivosEsp
    [Characteristics(ContainerCapacity = 0,
    CollectTransfertSpeed = 0,
    Scan = 5,
    MaxDamage = 5,
    DefenseDistance = 5,
    Constitution = 35)]

    class MiNanoObjetivo : NanoCollector
    {
        bool RestanMisionesEspCollector = true;
        
        public void DoNextObjetivo(MyAI Player)
        {
            Defensa.defenderse(Player,this);
            InternalName = "Misiones-Sp";
            
            foreach (Mision objeto in Player.lstMisionEspColectorTurnos)
            {
                if ((Player.CurrentTurn >= objeto.Empieza) && (Player.CurrentTurn <= objeto.Termina) && (RestanMisionesEspCollector = true))
                {
                    #region Misiones Especiales
                    //aca estoy en el rango de turnos para hacer las misiones especiales.

                    if (this.Location != objeto.ObjetivoPoint)
                    {
                        if (this.State == NanoBotState.WaitingOrders)
                        {
                            this.MoveTo(objeto.ObjetivoPoint);
                        }
                    }
                    else
                    {
                        this.StopMoving();
                        Player.lstMisionEspColectorTurnos.Remove(objeto);
                        if (Player.lstMisionEspColectorTurnos.Count == 0) RestanMisionesEspCollector = false;
                    }
                #endregion
                }
            }
                
            #region Misiones Normales
            
                    Point PuntoDeLaMision = Util.PuntoMasCercano(this.Location, Player.lstMisionEspColector,Player.lstMisionEspColectorExeptuados);

                    //si no estoy en el punto de objetivo mas cercano, voy a el.
                    if (this.Location != PuntoDeLaMision)
                    {
                        if (this.State == NanoBotState.WaitingOrders)
                        {
                            this.MoveTo(PuntoDeLaMision); 
                        }
                    }
                    //si estoy en el puntos de mision,borro el puntos de la lista para no volver a ir a ese.
                    else
                    {
                        this.StopMoving();
                        Player.lstMisionEspColectorExeptuados.Add(PuntoDeLaMision);
                    }
                    //si no hya mas puntos de mision sin recorrer me autodestruyo XD

                    if ((Player.lstMisionEspColectorExeptuados.Count == Player.lstMisionEspColector.Count + Player.LaDiferencia) && (RestanMisionesEspCollector == false)) {Player.HayMisionesEsp = false; this.ForceAutoDestruction(); }
                    #endregion

        }
    }
    #endregion

    #region MisionesExplorador
    [Characteristics(ContainerCapacity = 0,
    CollectTransfertSpeed = 0,
    Scan = 20,
    MaxDamage = 0,
    DefenseDistance = 0,
    Constitution = 20)]

    class MiNanoExplorador : NanoExplorer
    {

        public void DoNextExplorer(MyAI Player)
        {
            InternalName = "Explorador";
            Point PuntoDeLaMision = Util.PuntoMasCercano(this.Location, Player.lstMision,Player.lstMisionExeptuados);

            if (this.Location != PuntoDeLaMision)
            {
                if (this.State == NanoBotState.WaitingOrders)
                {
                    this.MoveTo(PuntoDeLaMision);
                }
            }
            else
            {
                this.StopMoving();
                Player.lstMisionExeptuados.Add(PuntoDeLaMision);
            }

            if (Player.lstMisionExeptuados.Count == Player.lstMision.Count) { this.ForceAutoDestruction(); Player.HayMisiones = false;}
        }

    }
    #endregion

    #region destructor
    [Characteristics(ContainerCapacity = 0,
    CollectTransfertSpeed = 0,
    Scan = 5,
    MaxDamage = 5,
    DefenseDistance = 12,
    Constitution = 28)]

    class MiNanoDestuctor : NanoCollector
    {

        public void DoNextDestructor(MyAI player)
        {
            InternalName = "Destructor";

            Point location = player.PierreTeamInjectionPoint;

            Defensa.defenderse(player, this);
            //this.atakar(player);
            if (this.Location != location)
            {
                this.MoveTo(location);
            }
            else
            {
                if (this.State == NanoBotState.WaitingOrders)
                {
                    player.PierreExtinto = true;
                    //this.ForceAutoDestruction();
                }
            }
            
        }

        public void atakar(MyAI player)
        {
            NanoBotInfo[] enemigos = player.OtherNanoBotsInfo;

            foreach (NanoBotInfo dePierre in enemigos)
            {
                //me fijo si lo que encontre es a pierre o al otro player
                //me fijo si estoy en rango de ataque y si me estoy moviendo, paro y ataco al enemigo
                if (Util.Distancia(this.Location, dePierre.Location) < this.DefenseDistance)
                {
                    if (this.State == NanoBotState.Moving) { this.StopMoving(); }
                    this.DefendTo(Util.PuntoMedio(Util.PuntoMedio(this.Location, dePierre.Location), dePierre.Location), dePierre.HitPoint / 4);// / BotAdefenderse.MaxDamage);
                }
            }
        }

    }

    #endregion

    #region needle
    [Characteristics(ContainerCapacity = 100,
    CollectTransfertSpeed = 0,
    Scan = 0,
    MaxDamage = 0,
    DefenseDistance = 0,
    Constitution = 50)]

    class Needle : NanoNeedle
    {

    }

    #endregion

    #region Torre
    [Characteristics(ContainerCapacity = 0,
    CollectTransfertSpeed = 0,
    Scan = 10,
    MaxDamage = 5,
    DefenseDistance = 10,
    Constitution = 125)]

    class MiNanoTorre : NanoNeedle
    {
        public void DoNextTorre(MyAI player)
        {
            InternalName = "Torre";
            if (player.PierreExtinto == true) { this.ForceAutoDestruction(); }

            Defensa.defenderse(player, this);
        }
    }

    #endregion


    class Defensa
    {

        public static void defenderse(MyAI player, MiNanoDestuctor BotAdefenderse)
        {
            NanoBotInfo[] enemigos = player.OtherNanoBotsInfo;

            foreach (NanoBotInfo dePierre in enemigos)
            {
                //me fijo si lo que encontre es a pierre o al otro player
                //me fijo si estoy en rango de ataque y si me estoy moviendo, paro y ataco al enemigo
                if (Util.Distancia(BotAdefenderse.Location, dePierre.Location) < BotAdefenderse.DefenseDistance)
                {
                    if (BotAdefenderse.State == NanoBotState.Moving) { BotAdefenderse.StopMoving(); }
                    BotAdefenderse.DefendTo(Util.PuntoMedio(Util.PuntoMedio(BotAdefenderse.Location, dePierre.Location), dePierre.Location), dePierre.HitPoint / 4);
                }
                    
            }
        }

        public static void defenderse(MyAI player, MiNanoObjetivo BotAdefenderse)
        {
            NanoBotInfo[] enemigos = player.OtherNanoBotsInfo;

            foreach (NanoBotInfo dePierre in enemigos)
            {
                //me fijo si lo que encontre es a pierre o al otro player
                //me fijo si estoy en rango de ataque y si me estoy moviendo, paro y ataco al enemigo
                if (Util.Distancia(BotAdefenderse.Location, dePierre.Location) < BotAdefenderse.DefenseDistance)
                {
                    if (BotAdefenderse.State == NanoBotState.Moving) { BotAdefenderse.StopMoving(); }
                    BotAdefenderse.DefendTo(Util.PuntoMedio(Util.PuntoMedio(BotAdefenderse.Location, dePierre.Location), dePierre.Location), dePierre.HitPoint / BotAdefenderse.MaxDamage);
                }
            }
        }

        public static void defenderse(MyAI player, MiNanoProtector BotAdefenderse)
        {
            NanoBotInfo[] enemigos = player.OtherNanoBotsInfo;

            foreach (NanoBotInfo dePierre in enemigos)
            {
                //me fijo si lo que encontre es a pierre o al otro player
                //me fijo si estoy en rango de ataque y si me estoy moviendo, paro y ataco al enemigo
                if (Util.Distancia(BotAdefenderse.Location, dePierre.Location) < BotAdefenderse.DefenseDistance)
                {
                    if (BotAdefenderse.State == NanoBotState.Moving) { BotAdefenderse.StopMoving(); }
                    BotAdefenderse.DefendTo(Util.PuntoMedio(Util.PuntoMedio(BotAdefenderse.Location, dePierre.Location), dePierre.Location), dePierre.HitPoint / BotAdefenderse.MaxDamage);
                }
            }
        }

        public static void defenderse(MyAI player, MiNanoTorre BotAdefenderse)
        {
            NanoBotInfo[] enemigos = player.OtherNanoBotsInfo;

            foreach (NanoBotInfo dePierre in enemigos)
            {
                if (Util.Distancia(BotAdefenderse.Location, dePierre.Location) < BotAdefenderse.DefenseDistance)
                {
                    BotAdefenderse.DefendTo(Util.PuntoMedio(Util.PuntoMedio(BotAdefenderse.Location, dePierre.Location), dePierre.Location), dePierre.HitPoint / BotAdefenderse.MaxDamage);
                }
            }
        }
    }

}